#!/usr/bin/env node

/**
 * 视频批量上传脚本
 * 
 * 用法:
 * node batch-upload-script.js --dir=./videos --token=your_auth_token --title="视频标题前缀" --desc="视频描述" --type=1 --labels=标签1,标签2 --cover=cover_file_id
 * 
 * 参数说明:
 * --dir: 视频文件所在目录（必需）
 * --token: 认证token（必需）
 * --title: 视频标题前缀，将添加到文件名前（可选）
 * --desc: 视频描述（可选）
 * --type: 视频分类ID（必需）
 * --labels: 视频标签，多个标签用逗号分隔（必需）
 * --cover: 视频封面文件ID（必需）
 * --help: 显示帮助信息
 */

const fs = require('fs');
const path = require('path');
const axios = require('axios');
const FormData = require('form-data');
const qiniu = require('qiniu-js');
const minimist = require('minimist');
const chalk = require('chalk');
const ora = require('ora');

// 解析命令行参数
const argv = minimist(process.argv.slice(2));

// 如果请求帮助或缺少必要参数，显示帮助信息
if (argv.help || !argv.dir || !argv.token || !argv.type || !argv.labels || !argv.cover) {
  console.log(chalk.yellow('\n视频批量上传脚本\n'));
  console.log('用法:');
  console.log('  node batch-upload-script.js --dir=./videos --token=your_auth_token --title="视频标题前缀" --desc="视频描述" --type=1 --labels=标签1,标签2 --cover=cover_file_id\n');
  console.log('参数说明:');
  console.log('  --dir: 视频文件所在目录（必需）');
  console.log('  --token: 认证token（必需）');
  console.log('  --title: 视频标题前缀，将添加到文件名前（可选）');
  console.log('  --desc: 视频描述（可选）');
  console.log('  --type: 视频分类ID（必需）');
  console.log('  --labels: 视频标签，多个标签用逗号分隔（必需）');
  console.log('  --cover: 视频封面文件ID（必需）');
  console.log('  --help: 显示帮助信息\n');
  process.exit(argv.help ? 0 : 1);
}

// 设置API基础URL
const BASE_URL = 'http://localhost:8080/luckyjourney'; // 根据实际情况修改

// 设置请求头的认证token
const axiosInstance = axios.create({
  baseURL: BASE_URL,
  headers: {
    'Authorization': argv.token
  }
});

// 支持的视频格式
const SUPPORTED_VIDEO_FORMATS = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.webm'];

/**
 * 获取七牛云上传token
 */
async function getQiniuToken() {
  try {
    const response = await axiosInstance.get('/video/token');
    if (response.data && response.data.state && response.data.data) {
      return response.data.data;
    } else {
      throw new Error('获取上传Token失败');
    }
  } catch (error) {
    console.error(chalk.red('获取七牛云上传Token失败:'), error.message);
    throw error;
  }
}

/**
 * 上传视频到七牛云
 * @param {File} file 视频文件
 * @param {string} token 七牛云上传token
 */
function uploadToQiniu(file, token) {
  return new Promise((resolve, reject) => {
    const spinner = ora(`上传 ${path.basename(file)} 到七牛云...`).start();
    
    const putExtra = {};
    const config = {
      useCdnDomain: true,
      region: null // 自动选择区域
    };

    // 读取文件
    const fileData = fs.readFileSync(file);
    const fileName = path.basename(file);
    
    // 创建文件对象，模拟浏览器的File对象
    const fileObj = {
      name: fileName,
      size: fileData.length,
      type: `video/${path.extname(file).substring(1)}`,
      _data: fileData
    };

    // 覆盖qiniu-js中的一些浏览器特定方法
    qiniu.compressedSize = {
      filter: () => false
    };

    // 创建自定义的FileReader
    const customFileReader = {
      readAsArrayBuffer: (data) => {
        return data._data.buffer;
      }
    };

    // 替换全局FileReader
    global.FileReader = function() {
      return customFileReader;
    };

    // 重写slice方法以适配Node环境
    fileObj.slice = function(start, end) {
      return {
        _data: this._data.slice(start, end)
      };
    };

    try {
      const observable = qiniu.upload(fileObj, null, token, putExtra, config);
      
      const subscription = observable.subscribe({
        next: (response) => {
          const percent = parseInt(response.total.percent);
          spinner.text = `上传 ${fileName} 到七牛云: ${percent}%`;
        },
        error: (error) => {
          spinner.fail(`上传 ${fileName} 失败: ${error.message}`);
          reject(error);
        },
        complete: (res) => {
          spinner.succeed(`上传 ${fileName} 成功`);
          resolve(res.key);
        }
      });
    } catch (error) {
      spinner.fail(`上传 ${fileName} 到七牛云失败: ${error.message}`);
      reject(error);
    }
  });
}

/**
 * 将视频信息保存到系统
 * @param {Object} videoInfo 视频信息对象
 */
async function saveVideoInfo(videoInfo) {
  try {
    const response = await axiosInstance.post('/video', videoInfo);
    if (response.data && response.data.state) {
      return response.data;
    } else {
      throw new Error(response.data?.message || '保存视频信息失败');
    }
  } catch (error) {
    console.error(chalk.red('保存视频信息失败:'), error.message);
    throw error;
  }
}

/**
 * 获取文件名（不带扩展名）
 * @param {string} filePath 文件路径
 * @returns {string} 不带扩展名的文件名
 */
function getFileNameWithoutExtension(filePath) {
  const basename = path.basename(filePath);
  return basename.substring(0, basename.lastIndexOf('.'));
}

/**
 * 主函数 - 批量上传视频
 */
async function batchUploadVideos() {
  try {
    console.log(chalk.blue('\n开始批量上传视频...\n'));
    
    // 检查目录是否存在
    if (!fs.existsSync(argv.dir)) {
      console.error(chalk.red(`目录 ${argv.dir} 不存在`));
      process.exit(1);
    }
    
    // 读取目录中的所有文件
    const files = fs.readdirSync(argv.dir)
      .filter(file => {
        const ext = path.extname(file).toLowerCase();
        return SUPPORTED_VIDEO_FORMATS.includes(ext);
      })
      .map(file => path.join(argv.dir, file));
    
    if (files.length === 0) {
      console.log(chalk.yellow('没有找到支持的视频文件'));
      process.exit(0);
    }
    
    console.log(chalk.green(`找到 ${files.length} 个视频文件\n`));
    
    // 获取七牛云上传token
    const qiniuToken = await getQiniuToken();
    
    // 批量上传文件
    let successCount = 0;
    let failCount = 0;
    
    for (const file of files) {
      try {
        // 上传到七牛云
        console.log(chalk.blue(`处理文件: ${path.basename(file)}`));
        const fileKey = await uploadToQiniu(file, qiniuToken);
        
        // 保存视频信息
        const videoInfo = {
          title: (argv.title || '') + getFileNameWithoutExtension(file),
          description: argv.desc || '',
          url: fileKey,
          cover: argv.cover,
          typeId: parseInt(argv.type),
          labelNames: argv.labels,
          auditQueueStatus: true // 默认使用快速审核队列
        };
        
        const saveSpinner = ora('保存视频信息到系统...').start();
        await saveVideoInfo(videoInfo);
        saveSpinner.succeed(`视频 ${videoInfo.title} 保存成功`);
        
        successCount++;
      } catch (error) {
        console.error(chalk.red(`处理文件 ${file} 失败:`), error.message);
        failCount++;
      }
      
      console.log(''); // 添加空行分隔
    }
    
    console.log(chalk.green(`\n批量上传完成! 成功: ${successCount}, 失败: ${failCount}`));
    
  } catch (error) {
    console.error(chalk.red('\n批量上传失败:'), error.message);
    process.exit(1);
  }
}

// 执行主函数
batchUploadVideos(); 